﻿// Curling 2.0 POJ - 3009.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <queue>
#include <cstring>

//https://vjudge.csgrandeur.cn/problem/POJ-3009



using namespace std;
/*
在 MM-21 星球上，今年的奥运会之后，冰壶运动开始流行起来。但规则与我们的有些不同。冰壶比赛是在一块冰板上进行的，冰板上标有方形网眼。
他们只使用一块石头。游戏的目的是用最少的步数将石头从起点引向终点。

图 1 显示了游戏棋盘的一个示例。一些方格可能被积木占据。有两个特殊的方格，即起点和目标方格，这两个方格没有积木。(这两个方格是不同的。）
一旦棋子开始移动，它就会一直走下去，直到碰到一个积木为止。为了让石子到达目标，你可能需要让石子停下来，撞上一个木块，然后再扔一次。


图 1：棋盘示例（S：起点，G：终点）

石子的移动遵循以下规则：

开始时，石子静止在起点方格。
石子的移动仅限于 x 和 y 方向。禁止对角线移动。
当石块静止不动时，您可以通过投掷使其移动。您可以将它扔向任何方向，除非它立即被挡住（图 2(a)）。
投掷后，石子会一直向同一方向移动，直到出现以下情况之一：
石子击中一个木块（图 2(b)、(c)）。
石块停在被击中石块旁边的方格。
木块消失。
棋子离开棋盘。
游戏以失败告终。
石子到达目标方格。
石子停在目标方格，游戏以成功结束。
一局游戏中投掷石块的次数不能超过 10 次。如果石子在 10 次移动中没有到达目标位置，则游戏以失败告终。

图 2：石子移动

根据规则，我们想知道石头在开始时是否能到达目标，如果能，则需要最少的移动次数。

按照图 1 所示的初始配置，需要走 4 步棋才能将石子从起点带到终点。路线如图 3(a) 所示。注意，当棋子到达终点时，棋盘的配置发生了变化，如图 3(b)所示。


输入是一系列数据集。输入结束时，会出现一行包含两个 0 的空格。数据集的数量永远不会超过 100 个。

每个数据集的格式如下。

电路板的宽度（=w）和高度（=h）
棋盘第一行
...
棋盘的第 h 行

黑板的宽度和高度满足以下条件： 2 <= w <= 20，1 <= h <= 20。

每行由 w 个十进制数字组成，以空格分隔。数字描述了相应方格的状态。

0 空方格
1 块
2 开始位置
3 目标位置

The dataset for Fig. D-1 is as follows:

6 6
1 0 0 2 1 0
1 1 0 0 0 0
0 0 0 0 0 3
0 0 0 0 0 0
1 0 0 0 0 1
0 1 1 1 1 1

输出
对于每个数据集，打印一行十进制整数，表示从起点到目标的最小移动次数。如果没有这样的路线，则打印-1。每一行中除该数字外不得有任何其他字符。


输入
2 1
3 2
6 6
1 0 0 2 1 0
1 1 0 0 0 0
0 0 0 0 0 3
0 0 0 0 0 0
1 0 0 0 0 1
0 1 1 1 1 1
6 1
1 1 2 1 1 3
6 1
1 0 2 1 1 3
12 1
2 0 1 1 1 1 1 1 1 1 1 3
13 1
2 0 1 1 1 1 1 1 1 1 1 1 3
14 6
0 0 1 0 0 0 0 1 1 0 1 1 1 0
0 0 1 0 1 0 1 1 1 1 1 1 1 1
1 1 0 2 1 1 0 0 1 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 0
1 0 1 1 1 0 1 1 0 1 1 0 0 0
1 0 1 0 0 1 0 0 1 0 0 0 0 3
4 8
0 1 0 0
0 0 0 0
1 0 0 1
0 0 0 0
0 0 0 0
3 0 1 0
1 0 1 0
1 0 0 2
0 0

输出
1
4
-1
4
10
-1
*/


const int N = 22;
int gra[N][N];
int w, h, startx, starty;
int ans = 0x3f3f3f3f;

void dfs(int x, int y, int step);
void change(int x, int y, int addx, int addy, int step) {
	int newx = x + addx; int newy = y + addy;

	if (newx >= 0 && newx < h && newy >= 0 && newy < w && gra[newx][newy] == 1) {
		//不能往这个方向移动 
		return;
	}

	if (newx < 0 || newx >= h || newy < 0 || newy >= w) {
		//滑出街 不能移动
		return;
	}

	x += addx, y += addy;
	//开始滑动
	while (x >= 0 && x < h && y >= 0 && y < w) { 
		if (gra[x][y] == 3) {
			ans = min(step+1, ans);
			return;
		}
		else if (gra[x][y] == 1) {
			gra[x][y] = 0;
			dfs(x-addx, y-addy, step + 1);
			gra[x][y] = 1;  return;
		}
		x += addx, y += addy;
	}
}

void dfs(int x, int y, int step) {
	//向四个方向滑动
	if (step > 10) return;

	change(x, y, 0, 1, step);
	change(x, y, 0, -1, step);
	change(x, y, 1, 0, step);
	change(x, y, -1, 0, step);

	return ;
}

void solve() {
	ans = 0x3f3f3f3f;
	dfs(startx,starty,0);

	if (ans > 10) ans = -1;
	cout << ans << endl;
}

int main() {
	while (cin >> w >> h) {
		if (w == 0 && h == 0)break;
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> gra[i][j];
				if (gra[i][j] == 2) {
					startx = i; starty = j;
				}
			}
		}

		solve();
	}


	return 0;
}


/*
//TLE版本
const int N = 22;
vector<vector<int> > gra;

int vis[N][N];
vector<vector<vector<int> > > mapV;
int mapId;

int w, h;
int startx, starty; 
queue<vector<int> > q;


bool change(int x, int y, int step,int mapid, int addx, int addy) {
	if (step >= 10) return false;

	int newx = x + addx;
	int newy = y + addy;
	vector<vector<int> > currGra = mapV[mapid];

	if (newx >= 0 && newx < h && newy >= 0 && newy < w && currGra[newx][newy] == 1) {
		//这个方向走不动 
		return false;
	}
	

	while (newx >= 0 && newx < h && newy >= 0 && newy < w  ) {
		if (currGra[newx][newy] == 3) {
			return true;
		}
		if (1 == currGra[newx][newy]) {
			currGra[newx][newy] = 0;
			mapV.push_back(currGra);
			vector<int> t;  t.push_back(x); t.push_back(y); t.push_back(step + 1); t.push_back(mapId++);
			q.push(t);
			return  false;
		}
		x = newx; y = newy;
		newx = x + addx; newy = y + addy;
	}
	
	return false;
}

void solve() {
	memset(vis, 0, sizeof vis);
	mapId = 0;
	mapV.clear();

	while (!q.empty())q.pop();

	vis[startx][starty] = 1;
	vector<int> t;  t.push_back(startx); t.push_back(starty); t.push_back(0); t.push_back(mapId++);
	q.push( t);
	mapV.push_back(gra);

	while (!q.empty()) {
		int x = q.front()[0];
		int y = q.front()[1];
		int step = q.front()[2];
		int currid = q.front()[3];
		q.pop();
		vector<vector<int> > currgra = mapV[currid];

		//检查合法的移动 不出界外 移动次数没超过10 是否达到终点
		if (step > 10) {
			cout << -1 << endl; return;
		}
		else if (currgra[x][y] == 3) {
			cout << step << endl; return;
		}

		if (change(x, y, step, currid, 0, 1)) {
			cout << step+1 << endl; return;
		}
		if (change(x, y, step, currid, 0, -1)) {
			cout << step + 1 << endl; return;
		}
		if (change(x, y, step, currid, 1, 0)) {
			cout << step + 1 << endl; return;
		}
		if (change(x, y, step, currid, -1, 0)) {
			cout << step + 1 << endl; return;
		}
	}
	cout << -1 << endl;
	return;
}

int main()
{
	while (cin >> w >> h) {
		if (w == 0 && h == 0)break;
		gra.resize(N, vector<int>(N));
		for (int i = 0; i < h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> gra[i][j];
				if (gra[i][j] == 2) {
					startx = i; starty = j;
				}
			}
		}

		solve();
	}

	return 0;
}
*/
 